package com.hmdp.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

/**
 * @author TJS
 * @Description  全局唯一ID  https://www.bilibili.com/video/BV1cr4y1671t?p=49&vd_source=bda5ece524a5cc8f1f73003363c24712
 * @create 2023/1/2 15:57
 */
@Component
public class RedisIdWorker {
    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final long BEGIN_TIMESTMP = 1672617600L;

    private static final int COUNT_BITS = 32;

    @SuppressWarnings({"ConstantConditions"})
    public long nextId(String prefixKey) {
        //生成时间戳  当前时间 - 某一起始时间
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timeTamp = nowSecond - BEGIN_TIMESTMP;
        //生成序列号
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = redisTemplate.opsForValue().increment("icr:" + prefixKey + ":" + date);
        //返回的Long包装类，警告是因为可能为null，事实上并不会为null

        //拼接并返回  0 + 31位时间戳 + 32位序列号。
        return timeTamp << COUNT_BITS | count;

    }
}
